package cn.itcast.web.controller;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
public class LoginController extends  BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private ModuleService moduleService;

    /*
        url： /login.do
        作用：校验登陆
        参数：email(邮箱) ,password(密码)
        返回值： 登陆成功 home/main(后台首页) || 登陆失败： login.jsp()
     */
    @RequestMapping("/login")
    public String login(String email,String password){
        //1. 判断用户名与密码是否为空，如果两者有一者为空都是回到登陆页面
        if(StringUtils.isEmpty(email)||StringUtils.isEmpty(password)){
            request.setAttribute("error","用户名或者密码不能为空");
            //注意： login.jsp不在pages目录中，所以不要经过视图解析器，所以前面带上forward或者redirect
            return "forward:/login.jsp";
        }
        try {
            //2. 得到subject的对象
            Subject subject = SecurityUtils.getSubject();
            //3. 把邮箱与密码封装到Token里面
            UsernamePasswordToken token = new UsernamePasswordToken(email,password);

            //4. 使用subject发出登陆的请求,携带token过去, 这里的登录方法本质上是会调用realm里面的登陆方法
            subject.login(token);

            //5. 登陆成功得到一个登陆成功的对象, shiro登陆成功之后其实shiro本质上也会在session中做很多登陆成功标记
            User loginUser = (User) subject.getPrincipal();
            //这里做的不是登录成功标记，而且我们页面上需要使用登陆者的信息，所以我们保存登陆者的信息
            session.setAttribute("loginUser",loginUser);

            //6. 查看该登陆成功的用户的权限
            List<Module> moduleList = moduleService.findModuleByUser(loginUser);
            session.setAttribute("modules",moduleList);
            //返回到后台的首页
            return "home/main";
        } catch (UnknownAccountException e) { //如果一旦出现了该异常，代表不存在用户名
           request.setAttribute("error","用户名或者密码错误");
           return "forward:/login.jsp";
        }catch (IncorrectCredentialsException e){ //密码错误的异常
            request.setAttribute("error","用户名或者密码错误");
            return "forward:/login.jsp";
        }

    }





    /*
   url： /logout.do
   作用：注销
      方案一： 删除session中登录成功标记  session.removeAttribute()
      方案二： 直接销毁session
   返回值： 登陆页面
    */
    @RequestMapping("/logout")
    public String logout() {
        //得到subject对象
        Subject subject = SecurityUtils.getSubject();
        //调用subject的logout方法去注销，这里注销其实本质上销毁shiro在session的标记
        subject.logout();
        //直接销毁sesion
        session.invalidate();
        return "redirect:/login.jsp";

    }



    /*
      url： /home.do
      作用：进入欢迎页面,后台首页的第一次内容页面
      返回值： home/home
   */
    @RequestMapping("/home")
    public String home(){
        return "home/home";
    }
}
